package com.nio;

import org.junit.Test;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;

public class AsynchronousFileChannelDemo {
    // Future 读数据
    @Test
    public void futureRead() {
        Path path = Paths.get("F:\\niotest\\3.txt");
        AsynchronousFileChannel asynchronousFileChannel = null;
        try {
            asynchronousFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        long positon = 0;
        // 调用channel的read方法得到true
        Future<Integer> read = asynchronousFileChannel.read(byteBuffer, positon);
        // 判断操作是否完成isDone,返回true
        while (!read.isDone());
        // 切换读写模式
        byteBuffer.flip();
        // byteBuffer.limit() buffer的大小
        byte[] bytes = new byte[byteBuffer.limit()];
        byteBuffer.get(bytes);
        System.out.println(new String(bytes));
        byteBuffer.clear();
    }

    // Future 写数据
    @Test
    public void futureWrite() {
        Path path = Paths.get("F:\\niotest\\3.txt");
        AsynchronousFileChannel asynchronousFileChannel = null;
        try {
            asynchronousFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put("你好".getBytes());
        byteBuffer.flip();
        long positon = 0;
        // 调用channel的read方法得到true
        Future<Integer> read = asynchronousFileChannel.write(byteBuffer, positon);
        byteBuffer.clear();
        // 判断操作是否完成isDone,返回true
        while (!read.isDone());
        System.out.println("写完了");
    }

    // CompletionHandler 读数据
    @Test
    public void completionHandlerRead() {
        Path path = Paths.get("F:\\niotest\\3.txt");
        AsynchronousFileChannel asynchronousFileChannel = null;
        try {
            asynchronousFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        long positon = 0;
        // 调用channel的read方法得到true
        asynchronousFileChannel.read(byteBuffer, 0, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("result:"+result);
                // 切换读写模式
                attachment.flip();
                // byteBuffer.limit() buffer的大小
                byte[] bytes = new byte[attachment.limit()];
                attachment.get(bytes);
                System.out.println(new String(bytes));
                attachment.clear();
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("读取内容失败");
            }
        });

    }

    // CompletionHandler 写数据
    @Test
    public void completionHandlerWrite() {
        Path path = Paths.get("F:\\niotest\\3.txt");
        AsynchronousFileChannel asynchronousFileChannel = null;
        try {
            asynchronousFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put("你好".getBytes());
        byteBuffer.flip();
        long positon = 0;
        // 调用channel的read方法得到true
        asynchronousFileChannel.write(byteBuffer, 0, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("result:"+result);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("读取内容失败");
            }
        });
    }

    @Test
    public void charSetEncoderAndDecoder() throws CharacterCodingException {
        Charset charset = Charset.forName("UTF-8");
        // 1.获取编码器
        CharsetEncoder encoder = charset.newEncoder();
        // 2.获取解码器
        CharsetDecoder decoder = charset.newDecoder();
        // 3.获取解码编码的数据
        CharBuffer charBuffer = CharBuffer.allocate(1024);
        charBuffer.put("字节码编辑器");
        charBuffer.flip();

        // 4.编码
        ByteBuffer byteBuffer = encoder.encode(charBuffer);
        System.out.println("编码后");
        for (int i = 0; i < byteBuffer.limit(); i++) {
            System.out.println(byteBuffer.get());
        }

        // 5.解码
        byteBuffer.flip();
        CharBuffer decode = decoder.decode(byteBuffer);
        System.out.println("解码后");
        System.out.println(decode.toString());

        System.out.println("指定其他格式解码:");
        Charset charset1=Charset.forName("GBK");
        byteBuffer.flip();
        CharBuffer decode1 = charset1.decode(byteBuffer);
        System.out.println(decode1.toString());

    }

}
